function spreading_codes = generate_spreading_codes(num_users, spreading_factor, code_type)
% generate_spreading_codes - 生成CDMA系统的扩频码
%
% 输入参数:
%   num_users       - 用户数量
%   spreading_factor - 扩频因子
%   code_type       - 扩频码类型: 'Walsh', 'Gold', 'Kasami'
%
% 输出参数:
%   spreading_codes - 扩频码矩阵，每行是一个用户的扩频码

% 初始化扩频码矩阵
spreading_codes = zeros(num_users, spreading_factor);

switch code_type
    case 'Walsh'
        % 生成Walsh-Hadamard码
        % Walsh码是正交的，适合同步CDMA系统
        if log2(spreading_factor) ~= floor(log2(spreading_factor))
            error('Walsh码的扩频因子必须是2的幂次');
        end
        
        % 生成Hadamard矩阵
        hadamard_matrix = hadamard(spreading_factor);
        
        % 为每个用户分配不同的Walsh码
        for i = 1:num_users
            % 确保不超过扩频因子(Walsh码的数量)
            row_idx = mod(i-1, spreading_factor) + 1;
            % 转换为±1表示
            spreading_codes(i, :) = (hadamard_matrix(row_idx, :) + 1) / 2;
        end
        
    case 'Gold'
        % 生成Gold码
        % Gold码有良好的相关性质，适合异步CDMA系统
        % 这里简化生成过程，实际应使用特定多项式
        m = ceil(log2(spreading_factor));
        n = 2^m - 1;  % Gold码的长度
        
        % 如果扩频因子不是2^m-1的形式，则进行调整
        if spreading_factor ~= n
            warning('Gold码长度调整为 %d (接近 %d)', n, spreading_factor);
        end
        
        % 定义两个首选多项式 - 这里使用简化的多项式
        % 实际使用中应选择特定的多项式对
        poly1 = [1 0 0 1 1];  % 例如: x^4 + x + 1
        poly2 = [1 1 0 0 1];  % 例如: x^4 + x^3 + 1
        
        % 生成两个m序列
        seq1 = generate_m_sequence(poly1, n);
        seq2 = generate_m_sequence(poly2, n);
        
        % 生成Gold码集
        for i = 1:num_users
            % 对第二个序列进行循环移位
            shift = mod(i-1, n);
            seq2_shifted = circshift(seq2, [0, shift]);
            
            % Gold码是两个m序列的模2加
            gold_code = mod(seq1 + seq2_shifted, 2);
            
            % 存储Gold码
            if spreading_factor <= n
                spreading_codes(i, :) = gold_code(1:spreading_factor);
            else
                % 如果需要的扩频因子大于Gold码长度，则重复使用
                repeats = ceil(spreading_factor / n);
                extended_code = repmat(gold_code, 1, repeats);
                spreading_codes(i, :) = extended_code(1:spreading_factor);
            end
        end
        
    case 'Kasami'
        % 生成Kasami码
        % Kasami码有优秀的相关性质，适合需要大量码且互相关性要求高的场景
        m = ceil(log2(spreading_factor));
        n = 2^m - 1;  % 小集合Kasami码的长度
        
        % 如果扩频因子不是2^m-1形式，则进行调整
        if spreading_factor ~= n
            warning('Kasami码长度调整为 %d (接近 %d)', n, spreading_factor);
        end
        
        % 生成m序列
        poly = [1 0 0 0 1 0 1];  % 一个例子多项式: x^6 + x + 1
        m_seq = generate_m_sequence(poly, n);
        
        % 生成下抽取序列
        decimation = 2^(m/2) + 1;
        if mod(m, 2) ~= 0
            warning('对于非偶数m，Kasami码生成被简化');
            decimation = 2^floor(m/2) + 1;
        end
        
        % 生成小集合Kasami码
        for i = 1:num_users
            if i == 1
                % 第一个用户使用原始m序列
                kasami_code = m_seq;
            else
                % 对抽取序列进行移位
                shift = mod(i-2, n);
                decimated_seq = m_seq(1:decimation:end);
                decimated_seq = [decimated_seq zeros(1, n - length(decimated_seq))];
                shifted_seq = circshift(decimated_seq, [0, shift]);
                
                % Kasami码是m序列与移位抽取序列的模2和
                kasami_code = mod(m_seq + shifted_seq, 2);
            end
            
            % 存储Kasami码
            if spreading_factor <= n
                spreading_codes(i, :) = kasami_code(1:spreading_factor);
            else
                repeats = ceil(spreading_factor / n);
                extended_code = repmat(kasami_code, 1, repeats);
                spreading_codes(i, :) = extended_code(1:spreading_factor);
            end
        end
        
    otherwise
        error('不支持的扩频码类型: %s', code_type);
end

% 将0/1二进制码转换为-1/+1形式，以便于后续处理
spreading_codes = 2 * spreading_codes - 1;

end

% 辅助函数：生成m序列
function seq = generate_m_sequence(poly, length)
    % 多项式阶数
    r = numel(poly) - 1;
    
    % 初始化移位寄存器
    register = ones(1, r);
    
    % 生成序列
    seq = zeros(1, length);
    for i = 1:length
        % 输出当前值
        seq(i) = register(r);
        
        % 计算反馈
        feedback = mod(sum(poly(2:end) .* register(1:r-1)), 2);
        
        % 移位寄存器
        register = [feedback register(1:r-1)];
    end
end 